<?php
/*
This file is part of Bugzilla Printable Report

    Bugzilla Printable Report  is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Bugzilla Printable Report  is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Bugzilla Printable Report .  If not, see <http://www.gnu.org/licenses/>.
*/

//Bug Reports BugzillaPrintableReport Class File

class BugzillaPrintableReport{
	private $validate;
	private $data;
	private $view;

   function __construct() {

	  $this->validate = new BugzillaValidate();
	  $this->data =     new BugzillaData($this->validate->query);
	  $this->view =     new BugzillaView($this->data->array);

   }

   public function getHeader() {

       return $this->validate->view;
   }

   public function getStatus() {

       return $this->validate->statusView;
   }

   public function getHTML() {

       return $this->view->html;
   }

}

class BugzillaValidate {

    //where the built query is stored
    public $query;
    //this is what is printed on the title based on the query
    public $view;
    public $statusView;

    function __construct() {

                // initialize input validator
                $validate = new Validate();

                 //get bug_status value
		 if(!empty($_GET['bug_status'])) {
                 // check product field
                 $status = $_GET['bug_status'];

                 $multiStatusQuery = " AND b.bug_status IN (";

                 $count = 0;
                 $buildView = '';

                 foreach ($status as $row=>$statusInner) {

                 if($count != 0) {
                     $multiStatusQuery .= ", ";
                     $buildView .= ', ';
                 }
                                 

                 if (!$validate->string($statusInner, array('format' => VALIDATE_ALPHA_UPPER . VALIDATE_ALPHA_LOWER
                                                         . VALIDATE_SPACE . VALIDATE_NUM))) {
                      die("Status ($statusInner) is not a valid String.");
                 }

                 $multiStatusQuery .= "'$statusInner'";
                 $buildView .= $statusInner;

                 $count++;

                 }

                 $multiStatusQuery .= ") ";

                 $this->statusView .= $buildView;

                 //if status is empty don't change query. Show all bugs
                 if(!empty($status)) {

                   $bug_status_query .= $multiStatusQuery;

                 }

		 }

		 //add product to query if exist
		 if(!empty($_GET['product'])) {
                 // check product field
                 $product = $_GET['product'];

                 $multiProductQuery = " AND p.name IN (";

                 $count = 0;
                 $buildView = '';
                 
                 foreach ($product as $row=>$productinner) {

                 if($count != 0) {
                     $multiProductQuery .= ", ";
                     $buildView .= ', ';
                 }

                  //strip slashes before validation and query
                 $productinner = stripslashes($productinner);

                 if (!$validate->string($productinner, array('format' => VALIDATE_STREET, VALIDATE_EALPHA, VALIDATE_ALPHA_UPPER . VALIDATE_ALPHA_LOWER
                                                         . VALIDATE_SPACE . VALIDATE_NUM))) {
                      die("Product ($productinner) is not a valid String.");
                 }
                 $productinner = addslashes($productinner);

                 $multiProductQuery .= "'$productinner'";
                 $buildView .= $productinner;

                 $count++;

                 }

                 $multiProductQuery .= ") ";

                 $bus_status_view .= " " . $buildView;

                 $bug_status_query .= $multiProductQuery;
                 
		 }

                 //define date search
		 if(!empty($_GET['start_date']) || !empty($_GET['end_date'])) {

                 $date_type = $_GET['date_type'];

                 if ($date_type == "creation_ts" ||
                     $date_type == "delta_ts" ||
                     $date_type == "lastdiffed" ||
                     $date_type == "deadline") {

                     $date_view .= ucwords(" - $date_type");

                 } else {

                  //if $date_type value is wrong set it to the default
                  $date_type = "creation_ts";
                  $date_view .= " - Creation_ts";
                 }

		 }

		  //add ending date if exist
		 if(!empty($_GET['start_date'])) {

		 $start_date = $_GET['start_date'];
		 //validate date
                 if (!$validate->date($start_date, array("format" => "%Y-%m-%d"))) {
                      die("Start Date ($start_date) is not a valid date.");
                 }

		 $bug_status_query .= " AND b.$date_type >= '$start_date 00:00:00'";

		 $date_view .= " From $start_date";

		 }

		 //add ending date if exist
		 if(!empty($_GET['end_date'])) {

		 $end_date = $_GET['end_date'];
		 //validate date
                 if (!$validate->date($end_date, array("format" => "%Y-%m-%d"))) {
                      die("End Date ($end_date) is not a valid date.");
                 }

		 $bug_status_query .= " AND b.$date_type <= '$end_date 23:59:59'";

		 $date_view .= " To $end_date";
		 
		 }

	$this->query = $bug_status_query;
	$this->view =  $bus_status_view . " Bugs " . $date_view;
	}
}

class BugzillaData {

    //this is where the main query is stored
    public $query;
    //this is where the finished array is stored
    public $array;
    //this is where the pear DB objsect is stored
    private $dataOb;

    function __construct($query) {

    //variables stored in the config.php
    global $dsn,$options;

	  //create the database object
          $bugsDB =& DB::connect($dsn, $options);

          if (PEAR::isError($bugsDB)) {
              die($bugsDB->getMessage());
          }

          //set the fetchmode to ordered
          $bugsDB->setFetchMode(DB_FETCHMODE_ORDERED);

		$this->dataOb = $bugsDB;
		$this->query = $query;

                //run the query
                $this->dataQuery();

         $this->dataOb->disconnect();

	}

	function dataQuery() {

         //main DB query
	 $query = "SELECT b.bug_id, b.priority, b.resolution, b.short_desc, p.name AS product,
                          c.name AS component, u.login_name AS owner, b.bug_severity AS type, b.bug_status, b.deadline
                   FROM bugs b, components c, products p, profiles u
                   WHERE b.product_id = p.id
                   AND b.component_id = c.id
                   " .$this->query. "
                   AND b.assigned_to = u.userid
                   ORDER BY b.priority ASC, b.bug_status, b.creation_ts ASC";

         //query the database
         $res =& $this->dataOb->query($query);

          if (PEAR::isError($res)) {
              die($res->getMessage());
          }

          $i = 0;
          //create the array
          while ($res->fetchInto($row)) {

	         $arrData[$i]['id'] .= $row[0];
	         $arrData[$i]['priority'] .= $row[1];
		 $arrData[$i]['resolution'] .= $row[2];
		 $arrData[$i]['short_desc'] .= $row[3];
		 $arrData[$i]['product'] .= $row[4];
		 $arrData[$i]['component'] .= $row[5];
		 $arrData[$i]['owner'] .= $row[6];
		 $arrData[$i]['type'] .= $row[7];
                 $arrData[$i]['bug_status'] .= $row[8];
                 $arrData[$i]['deadline'] .= $row[9];

		        //get each Comment and description
                        //this is run for each bug found
		        $queryComment = "SELECT l.bug_when, l.thetext, p.realname
                                         FROM longdescs AS l, profiles AS p
				         WHERE l.who = p.userid AND
				         l.bug_id = " .$row[0]. "
				         ORDER BY l.bug_when";

	                //query the database
                        $resComment =& $this->dataOb->query($queryComment);

                        if (PEAR::isError($resComment)) {
                            die($resComment->getMessage());
			}

			$c = -1;
			while ($resComment->fetchInto($rowC)) {

                           //function to trade <br> for \r
                           $newText = bugsText($rowC[1]);

                           //the first row in the longdescs table is the description
                           if($c == -1) {
                               $arrData[$i]['descriptionBy'] = $rowC[2] . " " . $rowC[0];
                               $arrData[$i]['description'] = $newText;
                           }

                           //every row after the first is the comments
		           if($c > -1) {
                               $arrData[$i]['commentby'][$c] = $rowC[2] . " " . $rowC[0];
                               $arrData[$i]['comment'][$c] = $newText;
                           }

		        $c++;
                        }

	   $i++;

          }

         $this->array = $arrData;

	}
}

class BugzillaView {

    //this is where the html is stored
    public $html;
    private $array;
    private $anchor;

    function __construct($array) {

        //value stored in config.php
        global $showTOC,$showComments;

        $this->anchor .= "<ol>\n";

        $this->array = $array;

        //loop through the array
       for ( $i = 0; $i < sizeof($this->array); $i++) {
	         $id =            ($this->array[$i]['id']);
		 $priority =      ($this->array[$i]['priority']);
		 $resolution =    ($this->array[$i]['resolution']);
		 $short_desc =    ($this->array[$i]['short_desc']);
		 $product =       ($this->array[$i]['product']);
		 $component =     ($this->array[$i]['component']);
		 $owner =         ($this->array[$i]['owner']);
		 $type =          ($this->array[$i]['type']);
                 $bug_status =    ($this->array[$i]['bug_status']);
                 $deadline =      (substr($this->array[$i]['deadline'], 0, 10));
                 $descriptionBy = ($this->array[$i]['descriptionBy']);
                 $description =   ($this->array[$i]['description']);

         //create the toc
         $this->anchor .= '<li><a href="#' . $id . '">' .  $short_desc . ' (' . $priority . ')</a></li>' . "\n";

         $base .= "<h1>" . bugLink($id,$short_desc) . "</h1>\n
	           <i>Priority:</i> $priority <i>Type:</i> $type<br>\n
		   <i>Product:</i> $product <i>Status:</i> $bug_status<br>\n
		   <i>Component:</i> $component <i>Deadline:</i> $deadline<br>\n
		   <i>Owner:</i> $owner<br>\n
                   <i>Decription by:</i> $descriptionBy<br>\n";

         $base .= "<div id=main>$description</div><br>\n";

              if($showComments) {
                //get the comments out of the array
                for ( $c = 0; $c < sizeof($this->array[$i]['comment']); $c++) {
	              $commentBy = ($this->array[$i]['commentby'][$c]);
                      $comment = ($this->array[$i]['comment'][$c]);

                      $base .= "<i>Comment by:</i> $commentBy<br>\n";
                      $base .= "<div id=main>$comment</div><br>\n";
                 }
              }

        }

      $this->html = $base;

      $this->anchor .= "</ol>\n";

      //Add the TOC to top of html if $showTOC is true
      if($showTOC == true) {
          $this->html =  "<br>\n
                          <div id=toc><h3>Table of Contents</h3>\n
	                  $this->anchor</div><br>\n
                          $this->html";
      }

    }

}

?>
